package model;

import java.util.ArrayList;

public class StringAnalyser {

	public static final String CALC_CONST = "()+*-/^";
	public static final String NUMBER_CONST = "0123456789.";

	public static String getIdInString(final String term) {
		return term.substring(0, term.indexOf('=')).trim();
	}

	public static String getTermInString(String term) {
		return term.substring(term.indexOf("=") + 1).trim();
	}

	/**
	 * @param term
	 * @return null if there is no substring surrounded by ()
	 */
	public static StringPosVec getFirstInnerTermPos(String term) {
		int end = term.indexOf(')');

		for (int start = end; start > -1; start--) {
			if (term.charAt(start) == '(') {
				return new StringPosVec(start, end);
			}
		}
		return null;
	}

	/**
	 * changes the string target by replacing a part(pos(start,end)) with source
	 * 
	 * @param targetString
	 * @param sourceSource
	 * @param pos
	 * @return the new targetString
	 */
	public static String replacePart(String targetString, String sourceSource,
			StringPosVec pos) {
		return targetString.substring(0, pos.start) + sourceSource
				+ targetString.substring(pos.end + 1, targetString.length());
	}

	public static String getSubstringWithoutBraces(String target,
			StringPosVec pos) {
		String subterm = target.substring(pos.start, pos.end + 1);
		if (subterm.charAt(0) == '(') {
			subterm = remove(subterm, 0);
		}
		if (subterm.charAt(subterm.length() - 1) == ')') {
			subterm = remove(subterm, subterm.length() - 1);
		}
		return subterm;
	}

	public static String getSubTerm(String target, StringPosVec pos) {
		return target.substring(pos.start, pos.end + 1);
	}

	public static ArrayList getElementsInTermList(String term) {
		ArrayList list = new ArrayList();
		String y = "";
		for (int i = 0; i < term.length(); i++) {
			char x = term.charAt(i);
			if (CALC_CONST.indexOf(x) == -1) {
				y = y + x;
			} else if (y != "") {
				list.add(y);
				y = "";
			}
		}
		if (y != "") {
			list.add(y);
			y = "";
		}
		return list;
	}

	/**
	 * @param term
	 * @return NULL if its not a correct term
	 */
	public static String getOptimizedTerm(String term) {
		String noSpacesTerm = getTermWithoutSpaces(term);
		String y = "";
		for (int i = 0; i < noSpacesTerm.length(); i++) {
			char x = noSpacesTerm.charAt(i);

			if (x == '{')
				y = y + '(';
			else if (x == '}')
				y = y + ')';
			else if (x == '[')
				y = y + '(';
			else if (x == ']')
				y = y + ')';
			else if (x == ',')
				y = y + '.';
			else if ((NUMBER_CONST.indexOf(x) > -1)
					&& (i + 1 < noSpacesTerm.length())) {
				char x2 = noSpacesTerm.charAt(i + 1);
				if (x2 == ' ')
					return null; // error
				if ((NUMBER_CONST + CALC_CONST).indexOf(x2) == -1) {
					y = y + x + "*";
				} else
					y = y + x;
			} else if (x != ' ') {
				y = y + x;
			}
		}
		return y;
	}

	public static String getTermWithoutSpaces(String term) {
		String y = "";
		for (int i = 0; i < term.length(); i++) {
			char x = term.charAt(i);
			if (x != ' ') {
				y = y + x;
			}
		}
		return y;
	}

	public static String remove(String string, int pos) {
		String firstPart = "";
		String secondPart = "";
		if (pos > 0)
			firstPart = string.substring(0, pos);
		if (pos < string.length() - 1)
			secondPart = string.substring(pos + 1, string.length());
		return firstPart + secondPart;
	}

	public static ArrayList getVarsList(ArrayList list) {

		ArrayList newList = new ArrayList();
		String x;
		for (int i = 0; i < list.size(); i++) {
			x = (String) list.get(i);

			// check newList for duplicates:
			if (newList.indexOf(x) == -1) {
				newList.add(x);
			}

		}

		return newList;
	}

	public static boolean onlyOneOperator(String term) {
		return StringAnalyser.getElementsInTermList(term).size() == 2;
	}

	public static int getOperatorPos(String term) {
		for (int i = 0; i < term.length(); i++) {
			char c = term.charAt(i);
			if (CALC_CONST.indexOf(c) > -1)
				return i;
		}
		return -1;
	}

	public static StringPosVec getLastPotBlock(String term) {
		int opPos = getLastPos(term, '^');
		if (opPos == -1)
			return null;
		int leftVarPos = getVarPosLeftFrom(term, opPos);
		int rightVarPos = getVarPosRightFrom(term, opPos);
		return new StringPosVec(leftVarPos, rightVarPos);
	}

	public static int getVarPosLeftFrom(String term, int opPos) {
		int i = opPos - 1;
		while (i >= 0) {
			if (CALC_CONST.indexOf(term.charAt(i)) == -1) {
				i--;
			} else {
				return i + 1;
			}
		}
		return i + 1;
	}

	public static int getVarPosRightFrom(String term, int opPos) {
		int i = opPos + 1;
		while (i < term.length()) {
			if (CALC_CONST.indexOf(term.charAt(i)) == -1) {
				i++;
			} else {
				return i - 1;
			}
		}
		return i - 1;
	}

	public static int getLastPos(String term, char c) {
		for (int i = term.length() - 1; i > -1; i--) {
			if (term.charAt(i) == c)
				return i;
		}
		return -1;
	}

	public static StringPosVec getFirstCalcBlock(String term, char operator) {
		int opPos = term.indexOf(operator);
		if (opPos == -1)
			return null;
		int leftVarPos = getVarPosLeftFrom(term, opPos);
		int rightVarPos = getVarPosRightFrom(term, opPos);
		return new StringPosVec(leftVarPos, rightVarPos);
	}

	public static boolean noOperator(String term) {
		return StringAnalyser.getElementsInTermList(term).size() == 1;
	}

	public static boolean isANumber(String id) {
		try {
			Integer.parseInt(id);
			return true;
		} catch (NumberFormatException e) {
		}
		return false;
	}

}
